package com.fujitsu.cn.fnst.dao;

import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.fujitsu.cn.fnst.base.BaseDao;
import com.fujitsu.cn.fnst.base.CommonParamter;
import com.fujitsu.cn.fnst.base.DateUtils;
import com.fujitsu.cn.fnst.base.ReflectUtils;
import com.fujitsu.cn.fnst.entiy.Meeting;
import com.fujitsu.cn.fnst.entiy.MeetingBook;
import com.fujitsu.cn.fnst.enums.BookState;
import com.fujitsu.cn.fnst.exception.NotOneException;
import com.fujitsu.cn.fnst.model.MeetingModel;
import com.fujitsu.cn.fnst.service.MeetingService;

@Repository
public class MeetingBookDao extends BaseDao<MeetingBook> {
	@Resource
	private MeetingService meetingsService;
	private final static int MAX_RESULT = 30;

	public MeetingModel getMeetingState(int meetingId) {
		Meeting meeting = meetingsService.find(meetingId);
		return getMeetingState(meeting);
	}

	public MeetingModel getMeetingState(Meeting meeting) {
		if (meeting == null) {
			return null;
		}
		MeetingModel model = new MeetingModel();
		try {
			ReflectUtils.copy(meeting, model);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		Date now = new Date();
		criteria.add(Restrictions.eq("meetingId", meeting.getId()))
				.add(Restrictions.le("bookStartTime", now))
				.add(Restrictions.ge("bookEndTime", now));
		boolean used = query(criteria).size() >= 1;
		model.setUsed(used);
		return model;
	}

	public List<MeetingModel> getMeetingState(String where, String order) {
		List<MeetingModel> models = new ArrayList<MeetingModel>();
		List<Meeting> meetings = meetingsService.findByWhereAndOrder(where,
				order);
		for (Meeting meetings2 : meetings) {
			MeetingModel model = getMeetingState(meetings2);
			models.add(model);
		}
		return models;
	}

	@SuppressWarnings("unused")
	@Deprecated
	public String timeModel(String date, String beginTime, String endTime,
			String amount) throws ParseException {
		String dateBegin = date + " " + beginTime.toUpperCase();
		String dateEnd = date + " " + endTime.toUpperCase();
		Date beginDate = getDateformat().parse(dateBegin);
		Date endDate = getDateformat().parse(dateEnd);
		int amountInt = Integer.parseInt(amount.trim());
		return "hahh";
	}

	public void bookMeetingRoom(Date startTime, Date endTime, int meetingId,
			int userId, String workId, String title, String details) {
		Meeting meeting = meetingsService.find(meetingId);
		String name = meeting == null ? "无名" : meeting.getMeetingName();
		Date now = new Date();
		MeetingBook book = new MeetingBook(name, workId, meetingId, userId,
				DateUtils.getFormattedStartTime(startTime),
				DateUtils.getFormattedEndTime(endTime), title, details, now,
				now,
				DateUtils.getFormattedDate(startTime, endTime).size() / 2.0f,
				BookState.unExcuted.getState());
		getHibernateTemplate().save(book);
	}

	public List<MeetingBook> getMeetingRoomHistroy(int meetingId) {
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		criteria.setMaxResults(MAX_RESULT);
		criteria.add(Restrictions.eq("meetingId", meetingId)).addOrder(
				Order.desc("createTime"));
		List<MeetingBook> books = query(criteria);
		releaseSession(session);
		return books;
	}

	public List<MeetingBook> getUserHistroy(int useId) {
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		criteria.setMaxResults(MAX_RESULT);
		criteria.add(Restrictions.eq("userId", useId)).addOrder(
				Order.desc("createTime"));
		List<MeetingBook> books = query(criteria);
		releaseSession(session);
		return books;
	}

	public String getJSON(Date startTime, Date endTime, int userId) {
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		criteria.add(Restrictions.ge("bookStartTime", startTime))
				.add(Restrictions.le("bookEndTime", endTime))
				.add(Restrictions.eq("userId", userId))
				.addOrder(Order.asc("bookStartTime"));
		List<MeetingBook> books = query(criteria);
		String json = getJson(books);
		releaseSession(session);
		return json;
	}

	public List<MeetingBook> getBooks(Date startTime, Date endTime, int userId) {
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		criteria.add(Restrictions.ge("bookStartTime", startTime))
				.add(Restrictions.le("bookEndTime", endTime))
				.addOrder(Order.asc("bookStartTime"));
		if (userId != CommonParamter.ALL_USER) {
			criteria.add(Restrictions.eq("userId", userId));
		}
		List<MeetingBook> books = query(criteria);
		releaseSession(session);
		return books;
	}

	private String getJson(List<MeetingBook> books) {
		if (books != null && books.size() > 0) {
			StringBuilder sb = new StringBuilder();
			sb.append("[");
			for (MeetingBook book : books) {
				sb.append("{");
				sb.append("\"id\":");
				sb.append(book.getId());
				sb.append(",");
				sb.append("\"fullname\":\"");
				sb.append(book.getMeetingTitle());
				sb.append("\",");
				sb.append("\"confname\":\"");
				sb.append(book.getMeetingId());
				sb.append("\",");
				sb.append("\"confshortname\":\"");
				sb.append(book.getMeetingId());
				sb.append("\",");
				sb.append("\"description\":\"");
				sb.append(book.getMeetingDescription());
				sb.append("\",");
				sb.append("\"title\":\"");
				sb.append(book.getMeetingTitle());
				sb.append("\",");
				sb.append("\"topic\":\"");
				sb.append(book.getMeetingTitle());
				sb.append("\",");
				sb.append("\"start\":\"");
				sb.append(getDateformatWithDayAndTimeString(book
						.getBookStartTime()));
				sb.append("\",");
				sb.append("\"end\":\"");
				sb.append(getDateformatWithDayAndTimeString(book
						.getBookEndTime()));
				sb.append("\"}");
				sb.append(",");

			}
			sb.deleteCharAt(sb.length() - 1);
			sb.append("]");
			return sb.toString();
		}
		return null;
	}

	public List<MeetingBook> getBooks(Date startTime, int userId) {
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		criteria.add(Restrictions.ge("bookStartTime", startTime)).addOrder(
				Order.asc("bookStartTime"));
		if (userId != CommonParamter.ALL_USER) {
			criteria.add(Restrictions.eq("userId", userId));
		}
		List<MeetingBook> books = query(criteria);
		releaseSession(session);
		return books;
	}

	public List<MeetingBook> getHisBooks(Date endTime, int userId) {
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		criteria.add(Restrictions.le("bookEndTime", endTime)).addOrder(
				Order.asc("bookStartTime"));
		if (userId != CommonParamter.ALL_USER) {
			criteria.add(Restrictions.eq("userId", userId));
		}
		List<MeetingBook> books = query(criteria);
		releaseSession(session);
		return books;
	}

	public List<MeetingBook> getAllMeetingBooks() {
		return getBooks(new Date(), CommonParamter.ALL_USER);
	}

	public List<MeetingBook> getBooks(Date startTime, Date endTime, int userId,
			int meetingId) {
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		criteria.add(Restrictions.ge("bookStartTime", startTime)).addOrder(
				Order.asc("bookStartTime"));
		if (userId != CommonParamter.ALL_USER) {
			criteria.add(Restrictions.eq("userId", userId));
		}
		if (meetingId != CommonParamter.ALL_METTING) {
			criteria.add(Restrictions.eq("meetingId", meetingId));
		}
		List<MeetingBook> books = query(criteria);
		releaseSession(session);
		return books;
	}

	/***
	 * 
	 * @param beginDate
	 *            为开始日期,endDate 为结束日期
	 * @return
	 * ***/
	public List<Map<Integer, Float>> getTopFiveUsedMeetingRooms(Date beginDate,
			Date endDate) {
		Session session = getSession();
		String sql = "SELECT new map(meetingId as meetingId,SUM(amount) as amount) FROM MeetingBook  WHERE bookStartTime>=? and bookEndTime<=? GROUP BY meetingId";
		Query query = session.createQuery(sql);
		query.setMaxResults(5);
		query.setDate(0, beginDate);
		query.setDate(1, endDate);
		// query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
		List<Map<Integer, Float>> tops = query.list();
		releaseSession(session);
		return tops;
	}

	/***
	 * 
	 * @param beginDate
	 *            为开始日期,endDate 为结束日期
	 * @return
	 * ***/
	public List<Map<Integer, Float>> getTopFiveUsedPerson(Date beginDate,
			Date endDate) {
		Session session = getSession();
		String sql = "SELECT new map(userId as userId,SUM(amount) as amount) FROM MeetingBook  WHERE bookStartTime>=? and bookEndTime<=? GROUP BY userId";
		Query query = session.createQuery(sql);
		query.setMaxResults(5);
		query.setDate(0, beginDate);
		query.setDate(1, endDate);
		// query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
		List<Map<Integer, Float>> tops = query.list();
		releaseSession(session);
		return tops;
	}

	public static class Top {
		private int meetingId;
		private float amount;

		public int getMeetingId() {
			return meetingId;
		}

		public void setMeetingId(int meetingId) {
			this.meetingId = meetingId;
		}

		public Top(int meetingId, float amount) {
			super();
			this.meetingId = meetingId;
			this.amount = amount;
		}

		public float getAmount() {
			return amount;
		}

		public void setAmount(float amount) {
			this.amount = amount;
		}
	}

	public MeetingBook getMeetingBook(int meetingId, Date date, float clock) {
		MeetingBook book = null;
		Session session = getSession();
		try {
			Criteria criteria = session.createCriteria(MeetingBook.class);
			date = DateUtils.add(date, Calendar.HOUR, (int) clock);
			if (clock * 2 % 2 == 1) {
				date = DateUtils.add(date, Calendar.MINUTE, 30);
			}
			criteria.add(Restrictions.eq("meetingId", meetingId))
					.add(Restrictions.le("bookStartTime", date))
					.add(Restrictions.gt("bookEndTime", date));
			criteria.setMaxResults(1);

			book = query4One(criteria);
		} catch (Exception e) {
		}
		releaseSession(session);
		return book;
	}

	public List<MeetingBook> getAllMeetingsByTime(Date time) {
		Session session = getSession();
		Criteria criteria = session.createCriteria(MeetingBook.class);
		criteria.add(Restrictions.eq("bookStartTime", time)).add(
				Restrictions.eq("state", BookState.unExcuted.getState()));
         List<MeetingBook>books=query(criteria);
		releaseSession(session);
		return books;
	}
}
